package com.example.demo.webofficeImpl;

import cn.ljserver.tool.weboffice.v3.exception.FileNotExist;
import cn.ljserver.tool.weboffice.v3.model.DownloadInfo;
import cn.ljserver.tool.weboffice.v3.model.FileInfo;
import cn.ljserver.tool.weboffice.v3.model.UserPermission;
import cn.ljserver.tool.weboffice.v3.service.PreviewService;
import cn.ljserver.tool.weboffice.v3.util.HeaderUtils;
import com.example.demo.entity.User;
import com.example.demo.service.MyFileService;
import com.example.demo.service.MyUserService;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;

import java.util.Optional;

/**
 * 文件预览服务必要的接口实现
 * <br>
 * <a href="https://solution.wps.cn/docs/callback/preview.html">-详见官方文档-</a>
 */
@Component
public class PreviewServiceImpl implements PreviewService {

    @Inject
    private MyFileService fileService;
    @Inject
    private MyUserService userService;

    /**
     * 获取文件信息
     *
     * @param fileId 文件id <br>
     *               <a href="https://solution.wps.cn/docs/callback/preview.html#获取文件信息">-详见官方文档-</a>
     */
    @Override
    public FileInfo fetchFileInfo(String fileId) {
        // 解释说明下，这里在实际的设计中，需要将 文件信息 表 和历史文件版本表分开放
        // 这里是通过文件id，获取到当前文件最新一个版本的文件信息，并返回
        // 这里为了方便，所以设计成了一张表
        return fileService.fetchFile(fileId).toFileInfo();
        // 其实这里简单的逻辑就是，通过文件id获取文件数据，具体看service实现
    }

    /**
     * 获取文件下载地址
     *
     * @param fileId 文件id <br>
     *               <a href="https://solution.wps.cn/docs/callback/preview.html#获取文件下载地址">-详见官方文档-</a>
     */
    @Override
    public DownloadInfo fetchDownloadInfo(String fileId) {
        // 解释说明下，这里在实际的设计中，需要将 文件信息 表 和历史文件版本表分开放
        // 然后这里就会获取最后一个版本的文件并返回
        // 这里为了方便，所以设计成了一张表
        return Optional.ofNullable(fileId)
                // 这里解释下，通过fileService中的findById方法获取到数据
                .map(fileService::findByIdAndLastVersion)
                // 这里实际返回的只有一个url，只不过封装到对象了
                .map(f -> DownloadInfo.builder()
                        .url(f.getUrl())
                        .build())
                .orElseThrow(FileNotExist::new);               
                // 其实这里简单的逻辑就是， 通过文件id获取文件最后一个版本的文件信息
                // 或者你用mp，直接写sql等，一样的
    }

    /**
     * 获取用户文件权限
     *
     * @param fileId 文件id <br>
     *               <a href="https://solution.wps.cn/docs/callback/preview.html#文档用户权限">-详见官方文档-</a>
     */
    @Override
    public UserPermission fetchUserPermission(String fileId) {
        // 获取user信息
        // 通过token获取用户信息
        // 这里是将token中的id直接当成用户id，实际使用，应该是token需要在拦截器中做鉴权
        // 而userid应该是从token中解码来的，或者是 通过 HeaderUtils.getUserQuery 来获取，前提是，前端传递了此值
        // 即前端传递了 初始化了 customArgs 参数并赋值
        // <a href="https://solution.wps.cn/docs/web/quick-start.html#%E6%AD%A5%E9%AA%A4-3-%E5%88%9D%E5%A7%8B%E5%8C%96">前端初始化赋值，详见官网</a>
        Long userId = Long.valueOf(HeaderUtils.getWebOfficeToken());
        // 解释说明下，这里在实际的设计中，需要将 文件信息 表 和 用户权限 表 分开放
        // 这里为了方便，并没有设计表，返回了所有权限到前端
        // check file exists
        fileService.fetchFile(fileId);
        User user = userService.fetchUser(userId);
        // 构建user对应的文件权限
        return UserPermission.builder()
                .userId(String.valueOf(user.getId()))
                .read(true)
                .update(true)
                .rename(true)
                .download(true)
                .copy(true)
                .comment(true)
                .history(true)
                .build();
    }
}
